package com.linkgie.galaxyframework.utils;

import java.util.Collection;
import java.util.Iterator;
import java.util.function.Function;

public class TextUtils {
	
	public static final String[] EMPTY_ARRAY = {};

	public static boolean hasText(String str) {
		return (str != null && str.length() > 0 && containsText(str));
	}

	private static boolean containsText(CharSequence str) {
		int len = str.length();
		for (int i = 0; i < len; i++) {
			if (!Character.isWhitespace(str.charAt(i))) {
				return true;
			}
		}
		return false;
	}

	public static boolean isEmpty(String str) {
		return str == null || str.length() == 0;
	}

	public static boolean isNotBlank(String str) {
		return hasText(str);
	}

	public static boolean isBlank(String str) {
		return str == null || str.length() == 0 || !containsText(str);
	}

	public static String concat(String... strs) {
		if (strs == null || strs.length == 0) {
			return null;
		}
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < strs.length; i++) {
			builder.append(strs[i]);
		}
		return builder.toString();
	}

	public static String combine(String seperator, String... items) {
		if (items == null || items.length == 0) {
			return null;
		}
		StringBuilder builder = new StringBuilder(items[0]);
		for (int i = 1; i < items.length; i++) {
			builder.append(seperator);
			builder.append(items[i]);
		}
		return builder.toString();
	}

	public static <T> String combine(String seperator, Collection<T> items, Function<T, String> stringifyFunction) {
		if (items == null || items.size() ==0) {
			return null;
		}
		Iterator<String> textItems = CollectionUtils.iterator(items, stringifyFunction);
		return combine(seperator, textItems);
	}

	public static <T> String combine(String seperator, Iterator<T> items, Function<T, String> stringifyFunction) {
		if (items == null) {
			return null;
		}
		Iterator<String> textItems = CollectionUtils.cast(items, stringifyFunction);
		return combine(seperator, textItems);
	}

	public static String combine(String seperator, Collection<String> items) {
		if (items == null) {
			return null;
		}
		return combine(seperator, items.iterator());
	}

	public static String combine(String seperator, Iterator<String> items) {
		if (items == null) {
			return null;
		}
		if (!items.hasNext()) {
			return null;
		}
		StringBuilder builder = new StringBuilder(items.next());
		while (items.hasNext()) {
			builder.append(seperator);
			builder.append(items.next());
		}
		return builder.toString();
	}

	public static boolean equals(String str1, String str2) {
		if (str1 == str2) {
			return true;
		}
		if (str1 != null && str2 != null && str1.equals(str2)) {
			return true;
		}
		return false;
	}

	public static String trimAndAssertNotEmpty(String value) {
		return trimAndAssertNotEmpty(value, "Value is blank!");
	}

	public static String trimAndAssertNotEmpty(String value, String errorMessage) {
		if (value != null) {
			String retnValue = value.trim();
			if (retnValue.length() > 0) {
				return retnValue;
			}
		}
		throw new IllegalArgumentException(errorMessage);
	}

	/**
	 * 截断字符串两端空白，返回剩余的字符串；
	 * <p>
	 * 
	 * @param value
	 * @return
	 */
	public static String trim(String value) {
		return value == null ? null : value.trim();
	}

	/**
	 * 截断字符串两端空白，返回剩余的非空白字符串；
	 * <p>
	 * 
	 * 如果字符串是空白字符串，则返回 null；
	 * <p>
	 * 
	 * 与 {@link #trim(String)} 方法不同，此方法只会返回非空白字符串或者 null，不会返回长度为 0 的字符串；
	 * 
	 * @param value
	 * @return
	 */
	public static String trimToNotEmpty(String value) {
		if (value == null) {
			return null;
		}
		String v = value.trim();
		if (v.length() == 0) {
			return null;
		}
		return v;
	}

	/**
	 * 截断字符串两端空白，返回剩余的非空白字符串；
	 * <p>
	 * 
	 * 如果字符串是空白字符串，则返回参数指定的默认值；
	 * <p>
	 * 
	 * 与 {@link #trim(String)} 方法不同，此方法只会返回非空白字符串或者 null，不会返回长度为 0 的字符串；
	 * 
	 * @param value        要截断的值；
	 * @param defaultValue 默认值；
	 * @return
	 */
	public static String trimToNotEmpty(String value, String defaultValue) {
		if (value == null) {
			return defaultValue;
		}
		String v = value.trim();
		if (v.length() == 0) {
			return defaultValue;
		}
		return v;
	}

	/**
	 * 返回首个不为空白字符的索引；
	 * @param str
	 * @return
	 */
	public static int indexOfNonWhitespace(String str) {
		if (str == null) {
			throw new IllegalArgumentException("String is null!");
		}
		int length = str.length();
		for (int i = 0; i < length; i++) {
			if (!Character.isWhitespace(str.charAt(i))) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * 返回最后一个不为空白字符的索引；
	 * @param str
	 * @return
	 */
	public static int lastIndexOfNonWhitespace(String str) {
		if (str == null) {
			throw new IllegalArgumentException("String is null!");
		}
		int length = str.length();
		for (int i = length-1; i > -1; i--) {
			if (!Character.isWhitespace(str.charAt(i))) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * 字面上比较两个字符串是否相等；
	 * <p>
	 * 与 String.equals() 方法不同，此方法会忽略字符两端的空白字符；
	 * 
	 * @param str1 字符1；
	 * @param str2 字符2；
	 * @param ignoreCase 是否忽略大小写；
	 * @return
	 */
	public static boolean literalEquals(String str1, String str2, boolean ignoreCase) {
		if (str1 == str2) {
			return true;
		}
		if (str1 == null || str2 == null) {
			return false;
		}

		int startIndex1 = indexOfNonWhitespace(str1);
		int length1;
		if (startIndex1 < 0) {
			length1 = 0;
		} else {
			int endIndex1 = lastIndexOfNonWhitespace(str1);
			length1 = endIndex1 - startIndex1 + 1;
		}


		int startIndex2 = indexOfNonWhitespace(str2);
		int length2;
		if (startIndex2 < 0) {
			length2 = 0;
		} else {
			int endIndex2 = lastIndexOfNonWhitespace(str2);
			length2 = endIndex2 - startIndex2 + 1;
		}
		if (length1!= length2) {
			return false;
		}
		if (length1 == 0) {
			return true;
		}
		return str1.regionMatches(ignoreCase, startIndex1, str2, startIndex2, length1);
	}

	/**
	 * 以忽略大小写的方式检查指定文本是否以指定的后缀结尾；
	 * <p>
	 * 
	 * @param text
	 * @param suffix
	 * @return
	 */
	public static boolean endsWithIgnoreCase(String text, String suffix) {
		return text.regionMatches(true, text.length() - suffix.length(), suffix, 0, suffix.length());
	}

	/**
	 * 以忽略大小写的方式检查指定文本是否以指定的前缀开头；
	 * <p>
	 * 
	 * @param text   要检查的文本；
	 * @param prefix 前缀；
	 * @return
	 */
	public static boolean startsWithIgnoreCase(String text, String prefix) {
		return text.regionMatches(true, 0, prefix, 0, prefix.length());
	}


	public static boolean startswithIgnoreWhitespace(String str, char token) {
		if (str == null || str.length() == 0) {
			return false;
		}
		int length = str.length();
		for (int i = 0; i < length; i++) {
			char ch = str.charAt(i);
			if (!Character.isWhitespace(ch)) {
				// 第一个非空白字符，判断是否是指定的字符；
				return ch == token;
			}
		}
		return false;
	}

	public static boolean endswithIgnoreWhitespace(String str, char token) {
		if (str == null || str.length() == 0) {
			return false;
		}
		int length = str.length();
		for (int i = length-1; i > -1; i--) {
			char ch = str.charAt(i);
			if (!Character.isWhitespace(ch)) {
				// 第一个非空白字符，判断是否是指定的字符；
				return ch == token;
			}
		}
		return false;
	}

}
